#include"gui.h"
#include"gui_button.h"
#include"gui_container.h"
#include"gui_color.h"
#include"gui_event.h"
#include"gui_checkbox.h"
#include"gui_label.h"
#include"gui_text.h"
#include<assert.h>

void gui_select_mouse_motion(gui_select_t *select,int x,int y)
{
    dprintf("[gui_checkbox] gui mouse motion in spirit\n");
    gui_spirit_t *spirit=&select->spirit;
    if(!gui_mouse_motion(spirit,x,y))
        return 0;

    return -1;
}

void gui_select_mouse_press(gui_select_t *select,int btn,int x,int y)
{
    dprintf("[gui_checkbox] gui mouse press in spirit\n");
    gui_spirit_t *spirit=&select->spirit;
    if(!gui_mouse_btn_down(spirit,btn,x,y))
      return 0;
    return -1;
}

void gui_select_mouse_release(gui_select_t *select,int btn,int x,int y)
{
    dprintf("[gui_checkbox] gui mouse up in spirit\n");

    gui_spirit_t *spirit=&select->spirit;
    if(!gui_mouse_btn_up(spirit,btn,x,y))
       return 0;
    return -1;
}

static void gui_select_button_function(gui_spirit_t *button,gui_select_t *select)
{    
    int8_t idx=gui_select_button_idx(select,GUI_BUTTON(button));
    if(idx<0)
        return;
    
    if(select->select_status&(1<<idx)) //clear choose
        gui_select_choose(select,button,0);
    else 
        gui_select_choose(select,button,1); //choose 
}

int8_t gui_select_button_idx(gui_select_t *select,gui_button_t *button)
{
    int i;
    for(i=0;i<GUI_SELECT_ITEM_NUM;i++)
    {
        if(select->buttons[i]==button)
            return i;
    }
    return -1;
}

gui_spirit_t* gui_select_idx_to_label(gui_select_t *select,uint8_t idx)
{
    if(idx>GUI_SELECT_ITEM_NUM-1)
        return NULL;
    return select->labels[idx];
}

int8_t gui_select_label_idx(gui_select_t *select,gui_spirit_t *label)
{
    int i;
    for(i=0;i<GUI_SELECT_ITEM_NUM;i++)
    {
        if(select->labels[i]==label)
            return i;
    }
    return -1;
}


gui_button_t *gui_select_idx_to_button(gui_select_t *select,uint8_t idx)
{
    if(idx>GUI_SELECT_ITEM_NUM-1)
        return NULL;
    return select->buttons[idx];
}

void gui_select_label_set_text(gui_select_t *select,uint8_t label_idx,char *text)
{
    gui_spirit_t *spirit=gui_select_idx_to_label(select,label_idx);
    if(!spirit)
        return;
    gui_spirit_hide(spirit);
    gui_spirit_set_text(spirit,text);
    gui_spirit_show(spirit);
}

void gui_select_choose(gui_select_t *select,gui_button_t *button,uint8_t is_choose)
{
    static uint32_t old_color=GUI_COLOR_NONE;
    int8_t idx=gui_select_button_idx(select,button);
    if(idx<0)
        return;

    if(is_choose&&!button->disable)
    {
        select->select_status|=(1<<idx);
        select->select_nums++;
        old_color=button->color_idle; //save old color
        button->color_idle=GUI_RED;
        gui_button_change_status(button,GUI_BUTTON_IDLE);
        gui_button_t *btn=NULL;
        //single select box just disable other button
        if(select->type==GUI_SELECT_TYPE_SINGLE) 
        {
            list_traversal_all_owner_to_next(btn,&select->button_list,list)
                if(btn!=button)
                    gui_button_set_disable(btn);
        }
    }
    else 
    {
        if(!button->disable)
        {
            if(old_color!=GUI_COLOR_NONE)
            {
                select->select_status&=~(1<<idx);
                select->select_nums--;
                button->color_idle=old_color;
                gui_button_change_status(button,GUI_BUTTON_IDLE);
                gui_button_t *btn=NULL;
                if(select->type==GUI_SELECT_TYPE_SINGLE)
                {
                    list_traversal_all_owner_to_next(btn,&select->button_list,list)
                        if(btn!=button)
                            gui_button_set_enable(btn);
                }
            }
        }
    }
}

uint32_t gui_select_get_selects(gui_select_t *select)
{
    return select->select_status;
}

uint32_t gui_select_get_select_num(gui_select_t *select)
{
    return select->select_nums;
}

static void gui_select_show_all_item(gui_select_t *select)
{
    gui_spirit_show_children(&select->spirit);
}

void gui_select_show(gui_spirit_t *select)
{
    gui_spirit_show(select);
    gui_select_show_all_item(select);
}

void gui_select_set_multi(gui_select_t *select,int is_mul)
{
    if(!select)
        return;
    if(is_mul)
    select->type=GUI_SELECT_TYPE_MULTIPLE;
    else 
    select->type=GUI_SELECT_TYPE_SINGLE;
}

static int gui_select_create_item(gui_select_t *select)
{
    uint32_t i;
    gui_spirit_t *label;
    gui_spirit_t *button;
    char item_x=2;
    char item_y=2;

    for(i=0;i<GUI_SELECT_ITEM_NUM;i++)
    {
        button=gui_button_create();
        if(!button)
            return -1;
        gui_spirit_reset_size(button,GUI_SELECT_ITEM_BTN_W,GUI_SELECT_ITEM_BTN_H);
        //button->style.background_color=GUI_GRAY;

        //add to button list and register to buttons elements 
        list_add_tail(&GUI_BUTTON(button)->list,&select->button_list);
        select->buttons[i]=GUI_BUTTON(button);

        //create button press signal
        gui_signal_connect(button,"button_press",gui_select_button_function,select);

        label=gui_label_create("item");
        if(!label)
            return -1;
        label->style.font_color=select->spirit.style.font_color;
        label->style.background_color=GUI_RGB_SUB(select->spirit.style.background_color,50,50,50);
        label->style.font_align=select->spirit.style.font_align;
        //gui_spirit_reset_size(label,GUI_SELECT_LABEL_W,GUI_SELECT_LABEL_H);
        select->labels[i]=label;
        
        item_x=2;
        gui_spirit_set_pos(button,item_x,item_y);
        item_x+=GUI_SELECT_ITEM_BTN_W+2;
        gui_spirit_set_pos(label,item_x,item_y);
        item_y+=GUI_SELECT_ITEM_HEIGHT;   

        gui_container_add(GUI_CONTAINER(&select->spirit),button);
        gui_container_add(GUI_CONTAINER(&select->spirit),label);
    }
    return 0;
}

//create default select 
gui_spirit_t *gui_select_create()
{
    gui_select_t *select=malloc(sizeof(gui_select_t));
    if(!select)
        return NULL;
    select->type=GUI_SELECT_TYPE_SINGLE;
    select->select_nums=0;
    select->select_status=0;
    list_init(&select->button_list);

    for(int i=0;i<GUI_SELECT_ITEM_NUM;i++)
    {
        select->buttons[i]=NULL;
        select->labels[i]=NULL;
    }

    gui_spirit_t *spirit=&select->spirit;
    gui_spirit_init(spirit,0,0,GUI_SELECT_ITEM_WIDTH+1,GUI_SELECT_ITEM_NUM*GUI_SELECT_ITEM_HEIGHT+2);
    gui_spirit_set_type(spirit,GUI_SPIRIT_TYPE_SELECT);
    spirit->style.background_color=GUI_BLUE;
    spirit->style.font_align=GUI_ALIGN_NONE;
    spirit->style.font_color=GUI_BLACK;

    gui_container_t *container=gui_container_create(spirit);
    if(!container)
        return NULL;
    spirit->container=container;
    
    if(gui_select_create_item(select)<0)
        return NULL;

    return spirit;
}

